import * as React from "react";
import * as ReactDOM from "react-dom";
import * as clamp from './vendor/core/clamp';
import * as DOMMouseMoveTracker from './vendor/dom/DOMMouseMoveTracker';
import * as Locale from './vendor/stubs/Locale';
import * as cx from "./vendor/stubs/cx";


const PropTypes = React.PropTypes;

class FixedDataTableColumnResizeHandle extends React.PureComponent<any, any>{
  static propTypes = {
    visible: PropTypes.bool.isRequired,

    /**
     * This is the height of the line
     */
    height: PropTypes.number.isRequired,

    /**
     * Offset from left border of the table, please note
     * that the line is a border on diff. So this is really the
     * offset of the column itself.
     */
    leftOffset: PropTypes.number.isRequired,

    /**
     * Height of the clickable region of the line.
     * This is assumed to be at the top of the line.
     */
    knobHeight: PropTypes.number.isRequired,

    /**
     * The line is a border on a diff, so this is essentially
     * the width of column.
     */
    initialWidth: PropTypes.number,

    /**
     * The minimum width this dragger will collapse to
     */
    minWidth: PropTypes.number,

    /**
     * The maximum width this dragger will collapse to
     */
    maxWidth: PropTypes.number,

    /**
     * Initial click event on the header cell.
     */
    initialEvent: PropTypes.object,

    /**
     * When resizing is complete this is called.
     */
    onColumnResizeEnd: PropTypes.func,

    /**
     * Column key for the column being resized.
     */
    columnKey: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.number
    ]),
  }

  private _mouseMoveTracker;

  constructor(props) {
    super(props);
    this.state = {
      width: 0,
      cursorDelta: 0
    };

    this._onMove = this._onMove.bind(this);
    this._onColumnResizeEnd = this._onColumnResizeEnd.bind(this);
  }

  componentWillReceiveProps(/*object*/ newProps) {
    if (newProps.initialEvent && !this._mouseMoveTracker.isDragging()) {
      this._mouseMoveTracker.captureMouseMoves(newProps.initialEvent);
      this.setState({
        width: newProps.initialWidth,
        cursorDelta: newProps.initialWidth
      });
    }
  }

  componentDidMount() {
    this._mouseMoveTracker = new DOMMouseMoveTracker(
      this._onMove,
      this._onColumnResizeEnd,
      document.body
    );
  }

  componentWillUnmount() {
    this._mouseMoveTracker.releaseMouseMoves();
    this._mouseMoveTracker = null;
  }

  render() /*object*/ {
    var style: any = {
      width: this.state.width,
      height: this.props.height,
    };
    if (Locale.isRTL()) {
      style.right = this.props.leftOffset;
    } else {
      style.left = this.props.leftOffset;
    }
    return (
      <div
        className={cx({
          'fixedDataTableColumnResizerLineLayout/main': true,
          'fixedDataTableColumnResizerLineLayout/hiddenElem': !this.props.visible,
          'public/fixedDataTableColumnResizerLine/main': true,
        })}
        style={style}>
        <div
          className={cx('fixedDataTableColumnResizerLineLayout/mouseArea')}
          style={{ height: this.props.height }}
        />
      </div>
    );
  }

  _onMove(/*number*/ deltaX) {
    if (Locale.isRTL()) {
      deltaX = -deltaX;
    }
    var newWidth = this.state.cursorDelta + deltaX;
    var newColumnWidth =
      clamp(newWidth, this.props.minWidth, this.props.maxWidth);

    // Please note cursor delta is the different between the currently width
    // and the new width.
    this.setState({
      width: newColumnWidth,
      cursorDelta: newWidth
    });
  }

  _onColumnResizeEnd() {
    this._mouseMoveTracker.releaseMouseMoves();
    this.props.onColumnResizeEnd(
      this.state.width,
      this.props.columnKey
    );
  }
};

export default FixedDataTableColumnResizeHandle;
